home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _pers_tree.c < prev    next >
C/C++ Source or Header  |  1994-11-16  |  25KB  |  1,147 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _pers_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/pers_tree.h>
  16.  
  17.  
  18. #define LEFT 0
  19. #define RIGHT 1
  20. #define f_isred(p)   ((p)->f_color)
  21. #define c_isred(p)   ((p)->c_color)
  22. #define f_mred(p)    ((p)->f_color=1)
  23. #define c_mred(p)    ((p)->c_color=1)
  24. #define f_mblack(p)  ((p)->f_color=0)
  25. #define c_mblack(p)  ((p)->c_color=0)
  26. #define f_lchild(p)  ((p)->f_link[0])
  27. #define c_lchild(p)  ((p)->c_link[0])
  28. #define f_rchild(p)  ((p)->f_link[1])
  29. #define c_rchild(p)  ((p)->c_link[1])
  30. #define f_parent(p)  ((p)->f_link[2])
  31. #define c_parent(p)  ((p)->c_link[2])
  32. #define f_isleaf(p)  (f_lchild(p)==(p))
  33. #define c_isleaf(p)  (c_lchild(p)==(p))
  34.  
  35.  
  36. void pers_rb_tree::f_rbclear(F_pers_tree_node* p)
  37. { if (!(f_isleaf(p)))
  38.     { f_rbclear(f_lchild(p));
  39.       f_rbclear(f_rchild(p));
  40.      }
  41.   delete p;
  42.  }
  43.  
  44. void pers_rb_tree::c_rbclear(C_pers_tree_node* p)
  45. { if (!(c_isleaf(p)))
  46.     { c_rbclear(c_lchild(p));
  47.       c_rbclear(c_rchild(p));
  48.      }
  49.   delete p;
  50. }
  51.  
  52.  
  53. F_pers_tree_node* pers_rb_tree::f_rbsearch(F_pers_tree_node* p, Version i)
  54. {
  55.   F_pers_tree_node *q;
  56.   
  57.   q = f_rchild(p);
  58.   while (!(f_isleaf(q)))
  59.   {  
  60.     if (i == q->ver_stamp || vless(i, q->ver_stamp))
  61.       q = f_lchild(q);
  62.     else
  63.       q = f_rchild(q);
  64.   }
  65.   return(q);
  66. }
  67.  
  68. C_pers_tree_node* pers_rb_tree::c_rbsearch(C_pers_tree_node* p, Version i)
  69. {
  70.   C_pers_tree_node *q;
  71.   
  72.   q = c_rchild(p);
  73.   while (!(c_isleaf(q)))
  74.   {
  75.     if (i == q->vers_stamp || vless(i, q->vers_stamp))
  76.       q = c_lchild(q);
  77.     else
  78.       q = c_rchild(q);
  79.   }
  80.   return(q);
  81. }
  82.  
  83. F_pers_tree_node * pers_rb_tree::f_nleaf(pers_tree_node* newvalue, Version i)
  84. {
  85.   F_pers_tree_node* result = new F_pers_tree_node;
  86.  
  87.   f_mblack(result);
  88.   result->ver_stamp = i;
  89.   f_lchild(result) = f_rchild(result) = result;
  90.   result->poin_value = newvalue;
  91.   return(result);
  92. }
  93.  
  94. C_pers_tree_node * pers_rb_tree::c_nleaf(int newvalue, Version i)
  95. {
  96.   C_pers_tree_node* result = new C_pers_tree_node;
  97.  
  98.   c_mblack(result);
  99.   result->vers_stamp = i;
  100.   c_lchild(result) = c_rchild(result) = result;
  101.   result->col_value = newvalue;
  102.   return(result);
  103. }
  104.  
  105. F_pers_tree_node * pers_rb_tree::f_nnode(F_pers_tree_node* c1, F_pers_tree_node* c2)
  106. {
  107.   F_pers_tree_node* result = new F_pers_tree_node;
  108.  
  109.   f_mred(result);
  110.   if (vless(c1->ver_stamp, c2->ver_stamp))
  111.   {
  112.     f_lchild(result) = c1;
  113.     c1->f_right = 0;
  114.     f_rchild(result) = c2;
  115.     c2->f_right = 1;
  116.   }
  117.   else
  118.   {
  119.     f_lchild(result) = c2;
  120.     c2->f_right = 0;
  121.     f_rchild(result) = c1;
  122.     c1->f_right = 1;
  123.   }
  124.   f_parent(c1) = f_parent(c2) = result;
  125.   result->ver_stamp = (f_lchild(result))->ver_stamp;
  126.   result->poin_value = NULL;
  127.   return(result);
  128. }
  129.  
  130. C_pers_tree_node* pers_rb_tree::c_nnode(C_pers_tree_node* c1, C_pers_tree_node* c2)
  131. {
  132.   C_pers_tree_node* result = new C_pers_tree_node;
  133.  
  134.   c_mred(result);
  135.   if (vless(c1->vers_stamp, c2->vers_stamp))
  136.   {
  137.     c_lchild(result) = c1;
  138.     c1->c_right = 0;
  139.     c_rchild(result) = c2;
  140.     c2->c_right = 1;
  141.   }
  142.   else
  143.   {
  144.     c_lchild(result) = c2;
  145.     c2->c_right = 0;
  146.     c_rchild(result) = c1;
  147.     c1->c_right = 1;
  148.   }
  149.   c_parent(c1) = c_parent(c2) = result;
  150.   result->vers_stamp = (c_lchild(result))->vers_stamp;
  151.   result->col_value = 0;  
  152.   return(result);
  153. }
  154.  
  155. void  pers_rb_tree::f_single_rot(F_pers_tree_node* top_node, int dir)
  156. {
  157.   F_pers_tree_node *temp, *q;
  158.  
  159.   q = top_node->f_link[1-dir];
  160.   top_node->f_link[1-dir] = temp = q->f_link[dir];
  161.   temp->f_right = 1 - dir;
  162.   f_parent(temp) = top_node;
  163.   q->f_link[dir] = top_node;
  164.   temp = f_parent(top_node);
  165.   f_parent(top_node) = q;
  166.   q->f_right = top_node->f_right;
  167.   temp->f_link[top_node->f_right] = q;
  168.   f_parent(q) = temp;
  169.   top_node->f_right = dir;
  170.   return;
  171. }
  172.  
  173. void  pers_rb_tree::c_single_rot(C_pers_tree_node* top_node, int dir)
  174. {
  175.   C_pers_tree_node *temp, *q;
  176.  
  177.   q = top_node->c_link[1-dir];
  178.   top_node->c_link[1-dir] = temp = q->c_link[dir];
  179.   temp->c_right = 1 - dir;
  180.   c_parent(temp) = top_node;
  181.   q->c_link[dir] = top_node;
  182.   temp = c_parent(top_node);
  183.   c_parent(top_node) = q;
  184.   q->c_right = top_node->c_right;
  185.   temp->c_link[top_node->c_right] = q;
  186.   c_parent(q) = temp;
  187.   top_node->c_right = dir;
  188.   return;
  189. }
  190.  
  191.  
  192. void  pers_rb_tree::f_double_rot(F_pers_tree_node* top_node, int dir)
  193. {
  194.   F_pers_tree_node *q, *r, *temp;
  195.  
  196.   q = top_node->f_link[1-dir];
  197.   r = q->f_link[dir];
  198.   top_node->f_link[1-dir] = temp = r->f_link[dir];
  199.   temp->f_right = 1 - dir;
  200.   f_parent(temp) = top_node;
  201.   q->f_link[dir] = (temp = r->f_link[1-dir]);
  202.   temp->f_right = dir;
  203.   f_parent(temp) = q;
  204.   temp = f_parent(top_node);
  205.   r->f_right = top_node->f_right;
  206.   r->f_link[dir] = top_node;
  207.   f_parent(top_node) = r;
  208.   top_node->f_right = dir;
  209.   r->f_link[1-dir] = q;
  210.   f_parent(q) = r;
  211.   temp->f_link[r->f_right] = r;
  212.   f_parent(r) = temp;
  213.   return;
  214. }
  215.  
  216. void  pers_rb_tree::c_double_rot(C_pers_tree_node* top_node, int dir)
  217. {
  218.   C_pers_tree_node *q, *r, *temp;
  219.  
  220.   q = top_node->c_link[1-dir];
  221.   r = q->c_link[dir];
  222.   top_node->c_link[1-dir] = temp = r->c_link[dir];
  223.   temp->c_right = 1 - dir;
  224.   c_parent(temp) = top_node;
  225.   q->c_link[dir] = (temp = r->c_link[1-dir]);
  226.   temp->c_right = dir;
  227.   c_parent(temp) = q;
  228.   temp = c_parent(top_node);
  229.   r->c_right = top_node->c_right;
  230.   r->c_link[dir] = top_node;
  231.   c_parent(top_node) = r;
  232.   top_node->c_right = dir;
  233.   r->c_link[1-dir] = q;
  234.   c_parent(q) = r;
  235.   temp->c_link[r->c_right] = r;
  236.   c_parent(r) = temp;
  237.   return;
  238. }
  239.  
  240.  
  241. int pers_rb_tree::f_insert(F_pers_tree_node* head, pers_tree_node* newvalue, Version i)
  242. {
  243.   int aux_bool;
  244.   F_pers_tree_node *p, *q, *r, *aux_node;
  245.  
  246.   if (f_rchild(head) == NULL)
  247.   {
  248.     p = f_nleaf(newvalue, i);
  249.     p->f_right = 1;
  250.     f_parent(p) = head;
  251.     f_rchild(head) = p;
  252.     return(0);
  253.   }
  254.   p = f_rbsearch(head, i);
  255.   if (p->ver_stamp == i)
  256.   {
  257.     p->poin_value = newvalue;
  258.     return(1);
  259.   }
  260.   q = f_nleaf(newvalue, i);
  261.   aux_bool = p->f_right;
  262.   aux_node = f_parent(p);
  263.   r = f_nnode(p, q);
  264.   f_parent(r) = aux_node;
  265.   r->f_right = aux_bool;
  266.   aux_node->f_link[aux_bool] = r;
  267.   if (!f_isred(aux_node))
  268.   {
  269.     f_mblack(f_rchild(head));
  270.     return(0);
  271.   }
  272.   q = aux_node;
  273.   p = f_parent(q);
  274.   while ((f_isred(f_lchild(p))) && (f_isred(f_rchild(p))))
  275.   {
  276.     f_mblack(f_lchild(p));
  277.     f_mblack(f_rchild(p));
  278.     f_mred(p);
  279.     r = p;
  280.     q = f_parent(r);
  281.     if (!f_isred(q))
  282.     {
  283.       f_mblack(f_rchild(head));
  284.       return(0);
  285.     }
  286.     p = f_parent(q);
  287.   }
  288.   if (q->f_right == r->f_right)
  289.   {
  290.     f_mred(p);
  291.     f_mblack(q);
  292.     f_single_rot(p, 1-r->f_right);
  293.   }
  294.   else
  295.   {
  296.     f_mblack(r);
  297.     f_mred(p);
  298.     f_double_rot(p, r->f_right);
  299.   }
  300.   f_mblack(f_rchild(head));
  301.   return(0);
  302. }
  303.  
  304. int pers_rb_tree::c_insert(C_pers_tree_node* head, int newvalue, Version i)
  305. {
  306.   int aux_bool;
  307.   C_pers_tree_node *p, *q, *r, *aux_node;
  308.  
  309.   if (c_rchild(head) == NULL)
  310.   {
  311.     p = c_nleaf(newvalue, i);
  312.     p->c_right = 1;
  313.     c_parent(p) = head;
  314.     c_rchild(head) = p;
  315.     return(0);
  316.   }
  317.   p = c_rbsearch(head, i);
  318.   if (p->vers_stamp == i)
  319.   {
  320.     p->col_value = newvalue;
  321.     return(1);
  322.   }
  323.   q = c_nleaf(newvalue, i);
  324.   aux_bool = p->c_right;
  325.   aux_node = c_parent(p);
  326.   r = c_nnode(p, q);
  327.   c_parent(r) = aux_node;
  328.   r->c_right = aux_bool;
  329.   aux_node->c_link[aux_bool] = r;
  330.   if (!c_isred(aux_node))
  331.   {
  332.     c_mblack(c_rchild(head));
  333.     return(0);
  334.   }
  335.   q = aux_node;
  336.   p = c_parent(q);
  337.   while ((c_isred(c_lchild(p))) && (c_isred(c_rchild(p))))
  338.   {
  339.     c_mblack(c_lchild(p));
  340.     c_mblack(c_rchild(p));
  341.     c_mred(p);
  342.     r = p;
  343.     q = c_parent(r);
  344.     if (!c_isred(q))
  345.     {
  346.       c_mblack(c_rchild(head));
  347.       return(0);
  348.     }
  349.     p = c_parent(q);
  350.   }
  351.   if (q->c_right == r->c_right)
  352.   {
  353.     c_mred(p);
  354.     c_mblack(q);
  355.     c_single_rot(p, 1-r->c_right);
  356.   }
  357.   else
  358.   {
  359.     c_mblack(r);
  360.     c_mred(p);
  361.     c_double_rot(p, r->c_right);
  362.   }
  363.   c_mblack(c_rchild(head));
  364.   return(0);
  365. }
  366.  
  367.  
  368.  
  369. /* insert the new version in the appropriate position and update the 
  370.  * version list
  371.  */
  372.  
  373. void pers_rb_tree::del_version(Version) 
  374. { if (--v_list->count ==0) del_tree(); }
  375.  
  376. Version pers_rb_tree::copy_version(Version i) { return new_version(i); }
  377.  
  378. Version pers_rb_tree::new_version(Version i)
  379. {
  380.  
  381.   Version succ = v_list->vl.succ(i);
  382.   
  383.   ver_node p = new VER_pers_tree_node;
  384.  
  385.   if (succ != nil)
  386.      p->ser_num = (v_list->vl[i]->ser_num + v_list->vl[succ]->ser_num) / 2.0;
  387.   else 
  388.      p->ser_num = v_list->vl[i]->ser_num + 1000;
  389.  
  390.  
  391.   p->popul = v_list->vl[i]->popul;
  392.   p->acc_pointer = v_list->vl[i]->acc_pointer;
  393.   v_list->count++;
  394.   return v_list->vl.insert(p,i);
  395. }
  396.  
  397. /* implementation of the update step (change of left or right child)
  398.  * for a specific persistent node and update operation 
  399.  */
  400.  
  401. void pers_rb_tree::update(F_pers_tree_node* p, pers_tree_node* newvalue, Version i)
  402.   F_pers_tree_node *p1, *i1, *i2;
  403.  
  404.   Version ip = v_list->vl.succ(i);
  405.  
  406.   if (f_insert(p, newvalue, i) == 1) return;
  407.  
  408.   if (ip == nil || vless(ip,p->ver_stamp)) return;
  409.  
  410.   p1 = f_rbsearch(p, i);
  411.   if (p1->f_right)
  412.   {
  413.     i1 = f_lchild(f_parent(p1));
  414.     if (f_isleaf(i1))
  415.       goto la;
  416.     else
  417.       i1 = f_rchild(i1);
  418. la: while (p1 != f_rchild(p) && p1->f_right)
  419.       p1 = f_parent(p1);
  420.     if (p1 == f_rchild(p))
  421.       i2 = NULL;
  422.     else
  423.     {
  424.       i2 = f_rchild(f_parent(p1));
  425.       while (!f_isleaf(i2))
  426.         i2 = f_lchild(i2);
  427.     }
  428.   }
  429.   else
  430.   {
  431.     i2 = f_rchild(f_parent(p1));
  432.     if (f_isleaf(i2))
  433.       goto m;
  434.     else
  435.       i2 = f_lchild(i2);
  436.  m: while (p1->f_right == 0)
  437.       p1 = f_parent(p1);
  438.     i1 = f_lchild(f_parent(p1));
  439.     while (!f_isleaf(i1))
  440.       i1 = f_rchild(i1);
  441.   }
  442.   if (i2 == NULL || vless(ip, i2->ver_stamp))
  443.      f_insert(p, i1->poin_value, ip);
  444. }
  445.    
  446.  
  447. /* implementation of the update step (change of color) for a specific
  448.  * persistent node and update operation 
  449.  */
  450.  
  451. void pers_rb_tree::up_col(C_pers_tree_node* p, int newvalue, Version i)
  452.   C_pers_tree_node *p1, *i1, *i2;
  453.   
  454.   Version ip = v_list->vl.succ(i);
  455.  
  456.   if (c_insert(p, newvalue, i) == 1) return;
  457.  
  458.   if (ip ==nil  || vless(ip,p->vers_stamp)) return;
  459.  
  460.   p1 = c_rbsearch(p, i);
  461.   if (p1->c_right)
  462.   {
  463.     i1 = c_lchild(c_parent(p1));
  464.     if (c_isleaf(i1))
  465.       goto lb;
  466.     else
  467.       i1 = c_rchild(i1);
  468. lb: while (p1 != c_rchild(p) && p1->c_right)
  469.       p1 = c_parent(p1);
  470.     if (p1 == c_rchild(p))
  471.       i2 = NULL;
  472.     else
  473.     {
  474.       i2 = c_rchild(c_parent(p1));
  475.       while (!c_isleaf(i2))
  476.         i2 = c_lchild(i2);
  477.     }
  478.   }
  479.   else
  480.   {
  481.     i2 = c_rchild(c_parent(p1));
  482.     if (c_isleaf(i2))
  483.       goto ma;
  484.     else
  485.       i2 = c_lchild(i2);
  486. ma: while (p1->c_right == 0)
  487.       p1 = c_parent(p1);
  488.     i1 = c_lchild(c_parent(p1));
  489.     while (!c_isleaf(i1))
  490.       i1 = c_rchild(i1);
  491.   }
  492.   if (i2 == NULL || vless(ip, i2->vers_stamp))
  493.      c_insert(p, i1->col_value, ip);
  494. }
  495.    
  496.  
  497. /* implementation of the access step for a specific persistent node 
  498.  * and version 
  499.  */
  500.  
  501. pers_tree_node * pers_rb_tree::acc_step(F_pers_tree_node *head, Version i)
  502. {
  503.   F_pers_tree_node *q, *i1;
  504.  
  505.   q = f_rbsearch(head, i);
  506.   if (q->ver_stamp == i)
  507.     return(q->poin_value);
  508.   if (vless(q->ver_stamp, i))
  509.     return(q->poin_value);
  510.   if (q->f_right)
  511.   {
  512.      i1 = f_lchild(f_parent(q));
  513.      if (f_isleaf(i1))
  514.        goto t;
  515.      else
  516.        i1 = f_rchild(i1);
  517.   }
  518.   else
  519.   {
  520.     while (q->f_right == 0)
  521.       q = f_parent(q);
  522.     i1 = f_lchild(f_parent(q));
  523.     while (!f_isleaf(i1))
  524.       i1 = f_rchild(i1);
  525.   }
  526. t:return(i1->poin_value);
  527. }
  528.   
  529.  
  530.  
  531. /* find out whether a given persistent node is red or not in a 
  532.  * specific version 
  533.  */
  534.  
  535. int pers_rb_tree::isred(pers_tree_node* p, Version i)
  536. {
  537.   C_pers_tree_node *head, *q, *i1;
  538.   
  539.   if (isleaf(p))
  540.     return(0);
  541.   head = p->red;
  542.   q = c_rbsearch(head, i);
  543.   if (q->vers_stamp == i)
  544.     return(q->col_value);
  545.   if (vless(q->vers_stamp, i))
  546.     return(q->col_value);
  547.   if (q->c_right)
  548.   {  
  549.      i1 = c_lchild(c_parent(q));
  550.      if (c_isleaf(i1))
  551.        goto s;
  552.      else
  553.        i1 = c_rchild(i1);
  554.   }
  555.   else
  556.   {
  557.     while (q->c_right == 0)
  558.       q = c_parent(q);
  559.     i1 = c_lchild(c_parent(q));
  560.     while (!c_isleaf(i1))
  561.       i1 = c_rchild(i1);
  562.   }
  563. s:return(i1->col_value);
  564. }
  565.  
  566.  
  567. /* create a new leaf and initialize the fields with the appropriate values */
  568.  
  569. pers_tree_node* pers_rb_tree::newleaf(void* val, void* inf, pers_tree_node* pred, pers_tree_node* succ, Version i)
  570. {
  571.   pers_tree_node *result;
  572.   F_pers_tree_node *res1, *res2;
  573.   C_pers_tree_node *res3;
  574.   
  575.   result = new pers_tree_node;
  576.   res1   = new F_pers_tree_node;
  577.   res2   = new F_pers_tree_node;
  578.   res3   = new C_pers_tree_node;
  579.    
  580.     result->key = val;
  581.     result->info = inf;
  582.     result->parent = NULL;
  583.     result->right = 1;
  584.     result->is_leaf = 1;
  585.     result->copy = NULL;
  586.  
  587.     result->next = v_list->used;
  588.     v_list->used = result;
  589.  
  590.     res1->ver_stamp = res2->ver_stamp = res3->vers_stamp = i;
  591.  
  592.     f_lchild(res1) = f_rchild(res1) = f_parent(res1) = NULL;
  593.     f_lchild(res2) = f_rchild(res2) = f_parent(res2) = NULL;
  594.     c_lchild(res3) = c_rchild(res3) = c_parent(res3) = NULL;
  595.  
  596.     res1->f_right = res2->f_right = res3->c_right = 1;
  597.     res1->f_color = res2->f_color = res3->c_color = 0;
  598.  
  599.     res1->poin_value = res2->poin_value = NULL; 
  600.     res3->col_value = 0;  
  601.  
  602.     f_insert(res1, pred, i);
  603.     f_insert(res2, succ, i);
  604.     c_insert(res3, 0, i);
  605.  
  606.     result->link[0] = res1;
  607.     result->link[1] = res2;
  608.     result->red     = res3;
  609.  
  610.     return result;
  611. }
  612.  
  613. /* create a new persistent node and initialize its fields with the
  614.  * appropriate values 
  615.  */
  616.  
  617. pers_tree_node* pers_rb_tree::newnode(pers_tree_node* c1, pers_tree_node* c2, Version i)
  618. {
  619.   // c1 and c2 are leaves
  620.  
  621.   pers_tree_node *result;
  622.   F_pers_tree_node *res1, *res2,  *res4;   // s.n. : res4 pointer to leaf (copy)
  623.   C_pers_tree_node *res3;
  624.   
  625.   result = new pers_tree_node;
  626.   res1   = new F_pers_tree_node;
  627.   res2   = new F_pers_tree_node;
  628.   res3   = new C_pers_tree_node;
  629.   res4   = new F_pers_tree_node;
  630.  
  631.     result->parent = NULL;
  632.  
  633.     result->next = v_list->used;
  634.     v_list->used = result;
  635.  
  636.     res1->ver_stamp = res2->ver_stamp = res3->vers_stamp = i;
  637.  
  638.     f_lchild(res1) = f_rchild(res1) = f_parent(res1) = NULL;
  639.     f_lchild(res2) = f_rchild(res2) = f_parent(res2) = NULL;
  640.     f_lchild(res4) = f_rchild(res4) = f_parent(res4) = NULL;
  641.     c_lchild(res3) = c_rchild(res3) = c_parent(res3) = NULL;
  642.  
  643.     res1->f_right = res2->f_right = res3->c_right = res4->f_right = 1;
  644.     res1->f_color = res2->f_color = res3->c_color = res4->f_color = 0;
  645.  
  646.     res1->poin_value = res2->poin_value = res4->poin_value = NULL; 
  647.     res3->col_value = 1;  
  648.  
  649.     c_insert(res3, 1, i);
  650.  
  651.     if (cmp_keys(c1->key, c2->key) < 1)
  652.     {
  653.       f_insert(res1, c1, i);
  654.       f_insert(res2, c2, i);
  655.       f_insert(res4, c1, i);
  656.       result->key = c1->key;
  657.     }
  658.     else
  659.     {
  660.       f_insert(res1, c2, i);
  661.       f_insert(res2, c1, i);
  662.       f_insert(res4, c2, i);
  663.       result->key = c2->key;
  664.     }
  665.  
  666.     result->link[0] = res1;
  667.     result->link[1] = res2;
  668.     result->red     = res3;
  669.     result->copy    = res4;
  670.     result->is_leaf = 0;
  671.  
  672.     return(result);
  673. }
  674.  
  675.   
  676. /* implementation of the single rotation for the fully persistent
  677.  * red-black tree
  678.  */
  679.  
  680. pers_tree_node* pers_rb_tree::single_rot(pers_tree_node* top_node, int dir, Version i)
  681. {
  682.   pers_tree_node *temp, *q, *newroot;
  683.   
  684.   newroot = NULL;
  685.   q = child(1 - dir, top_node, i);
  686.   temp = child(dir, q, i);
  687.   update(top_node->link[1 - dir], temp, i);
  688.   update(q->link[dir], top_node, i);
  689.   if ((temp = top_node->parent) == NULL)
  690.     newroot = q;
  691.   top_node->parent = q;
  692.   if (temp != NULL)
  693.     update(temp->link[top_node->right], q, i);
  694.   top_node->right = dir;
  695.   return(newroot);
  696. }
  697.  
  698. /* implementation of the double rotation for the fully persistent
  699.  * red-black tree
  700.  */
  701.  
  702. pers_tree_node* pers_rb_tree::double_rot(pers_tree_node* top_node, int dir, Version i)
  703. {
  704.   pers_tree_node *q, *r, *temp, *newroot;
  705.   
  706.   newroot = NULL;
  707.   q = child(1 - dir, top_node, i);
  708.   r = child(dir, q, i);
  709.   temp = child(dir, r, i);
  710.   update(top_node->link[1 - dir], temp, i);
  711.   temp = child(1 - dir, r, i);
  712.   update(q->link[dir], temp, i);
  713.   if ((temp = top_node->parent) == NULL)
  714.     newroot = r;
  715.   update(r->link[dir], top_node, i);
  716.   update(r->link[1 - dir], q, i);
  717.   if (temp != NULL)
  718.     update(temp->link[top_node->right], r, i);
  719.   return(newroot);
  720. }
  721.  
  722. /* the root is colored black after each  update operation */
  723.  
  724. void pers_rb_tree::m_b_root(Version i)
  725. {
  726.   pers_tree_node *p;
  727.  
  728.   p = v_list->vl[i]->acc_pointer;
  729.  
  730.   if (p != NULL && !isleaf(p) && isred(p, i))
  731.      up_col(p->red, 0, i);
  732. }
  733.  
  734.  
  735.  
  736.  
  737. //------------------------------------------------------------------------------
  738. // member functions
  739. //------------------------------------------------------------------------------
  740.  
  741.  
  742. void pers_rb_tree::init_tree()
  743. {
  744.    /* create dummy (empty) version 0 */
  745.    ver_node v = new VER_pers_tree_node;
  746.    v->ser_num =  0;
  747.    v->popul   =  0;
  748.    v->acc_pointer = NULL;
  749.    v_list = new V_LIST;
  750.    v_list->vl.append(v);
  751.    v_list->count = 1;
  752.  
  753.    v_list->used = NULL;
  754.  
  755. }
  756.  
  757. pers_tree_node* pers_rb_tree::search(void *val, pers_tree_node*& copy, Version i)
  758. {
  759.   pers_tree_node *p, *q;
  760.  
  761.   copy = NULL;
  762.   
  763.   if ((p = v_list->vl[i]->acc_pointer) == NULL)
  764.     return(NULL);
  765.  
  766.   p->parent = NULL;
  767.   p->right = 1;
  768.   while (!isleaf(p))
  769.   {
  770.     int v = cmp_keys(val, get_key(p,i));
  771.  
  772.     if (v < 1)
  773.     { if (v==0) copy = p;
  774.       q = p;
  775.       p = child(0, p, i);
  776.       p->parent = q;
  777.       p->right = 0;
  778.      }
  779.     else
  780.     { q = p;
  781.       p = child(1, p, i);
  782.       p->parent = q;
  783.       p->right = 1;
  784.      }
  785.    }
  786.  
  787.    return p;
  788. }
  789.  
  790.  
  791.  
  792. Version  pers_rb_tree::del(void *val, Version i1)
  793. {
  794.   pers_tree_node *pos_del, *par1, *par2, *root, *newroot, *temp, *copy;
  795.  
  796.   Version i  = new_version(i1);
  797.   
  798.   if ((pos_del = search(val, copy, i1)) == NULL) return i; //empty tree
  799.  
  800.   if (cmp_keys(pos_del->key, val) != 0) return i;  // key not found
  801.  
  802.  
  803.   if ((--(v_list->vl[i]->popul)) == 0)
  804.   {
  805.     v_list->vl[i]->acc_pointer = NULL;
  806.     return i;
  807.   }
  808.  
  809.  
  810.   //update links to neighbor leaves
  811.  
  812.   pers_tree_node* pred = child(0,pos_del,i);
  813.   pers_tree_node* succ = child(1,pos_del,i);
  814.  
  815.   if (pred) update(pred->link[1],succ,i);
  816.   if (succ) update(succ->link[0],pred,i);
  817.  
  818.  
  819.   root = v_list->vl[i]->acc_pointer;
  820.  
  821.   if ((par1 = pos_del->parent) == root)
  822.   {
  823.     v_list->vl[i]->acc_pointer = sibling(pos_del, i);
  824.     goto end;
  825.    }
  826.  
  827.   par2 = par1->parent;
  828.   pos_del = sibling(pos_del, i);
  829.   update(par2->link[par1->right], pos_del, i);
  830.   pos_del->parent = par2;
  831.   pos_del->right = par1->right;
  832.  
  833.   if (copy != NULL && copy != par1)  // we have to overwrite copy  by pred
  834.   {
  835.     update(copy->copy, pred, i);
  836.  
  837.    }
  838.   
  839.  
  840.   if (isred(par1, i))
  841.     goto end;
  842.   if (isred(pos_del, i))
  843.   {
  844.     up_col(pos_del->red, 0, i);
  845.     goto end;
  846.   }
  847.   par1 = sibling(pos_del, i);
  848.   while ((!isred(par1, i)) && (!isred(child(0, par1, i), i)) &&
  849.          (!isred(child(1, par1, i), i)))
  850.   {
  851.     up_col(par1->red, 1, i);
  852.     pos_del = pos_del->parent;
  853.     if (isred(pos_del, i))
  854.     {
  855.       up_col(pos_del->red, 0, i);
  856.       goto end;
  857.     }
  858.     if (pos_del == root)
  859.       goto end;
  860.     else
  861.       par1 = sibling(pos_del, i);
  862.   }
  863.   par2 = pos_del->parent;
  864.   if (isred(par1, i))
  865.   {
  866.     up_col(par2->red, 1, i);
  867.     up_col(par1->red, 0,i);
  868.     if ((newroot = single_rot(par2, pos_del->right, i)) != NULL)
  869.       v_list->vl[i]->acc_pointer = newroot;
  870.     par1 = sibling(pos_del,i);
  871.     if ((!isred(child(0, par1, i), i)) && (!isred(child(1, par1, i), i)))
  872.     {
  873.       up_col(par1->red, 1, i);
  874.       up_col((pos_del->parent)->red, 0, i);
  875.       goto end;
  876.     }
  877.   }
  878.   par2 = pos_del->parent;
  879.   if (!pos_del->right)
  880.     if (isred(child(0, par1, i), i))
  881.     {
  882.       temp = child(0, par1, i);
  883.       up_col(temp->red, isred(par2, i), i);
  884.       up_col(par2->red, 0, i);
  885.       newroot = double_rot(par2, LEFT, i);
  886.     }
  887.     else
  888.     {
  889.       up_col(par1->red, isred(par2, i), i);
  890.       up_col(par2->red, 0, i);
  891.       temp = child(1, par1, i);
  892.       up_col(temp->red, 0, i);
  893.       newroot = single_rot(par2, LEFT, i);
  894.     }
  895.   else
  896.     if (isred(child(0, par1, i), i))
  897.     {
  898.       up_col(par1->red, isred(par2, i), i);
  899.       up_col(par2->red, 0, i);
  900.       temp = child(0, par1, i);
  901.       up_col(temp->red, 0, i);
  902.       newroot = single_rot(par2, RIGHT, i);
  903.     }
  904.     else
  905.     {
  906.       temp = child(1, par1, i);
  907.       up_col(temp->red, isred(par2, i), i);
  908.       up_col(par2->red, 0, i);
  909.       newroot = double_rot(par2, RIGHT, i);
  910.     }
  911.   if (newroot != NULL)
  912.     v_list->vl[i]->acc_pointer = newroot;
  913.  
  914. end:
  915.   m_b_root(i);
  916.   return i;
  917. }
  918.  
  919.  
  920. Version pers_rb_tree::insert(void *val, void* info, Version i1)
  921. {
  922.   int aux_bool; 
  923.   pers_tree_node *p, *q, *r, *aux_node, *root, *newroot, *temp;
  924.  
  925.   Version i = new_version(i1);
  926.  
  927.   p = search(val, i1);
  928.  
  929.   if (p && cmp_keys(p->key, val) == 0) return i;  // key already there
  930.  
  931.   copy_key(val);
  932.   copy_inf(info);
  933.   
  934.   if (p == NULL)   // empty tree
  935.   { p = newleaf(val, info, nil, nil, i);
  936.     v_list->vl[i]->acc_pointer = p;
  937.     v_list->vl[i]->popul = 1;
  938.     goto end;
  939.    }
  940.  
  941.   (v_list->vl[i]->popul)++;
  942.  
  943.   if (cmp_keys(val, p->key) > 0)   // new rightmost leaf 
  944.     { q = newleaf(val,info, p, nil, i);   
  945.       update(p->link[1], q, i);
  946.      }
  947.   else // new  leaf before  p 
  948.     { pers_tree_node * pred = child(0,p,i);
  949.       q = newleaf(val,info, pred, p, i);   
  950.       update(p->link[0], q, i);
  951.       if (pred) update(pred->link[1], q, i);
  952.      }
  953.  
  954.   aux_bool = p->right;
  955.   r = newnode(p, q, i);
  956.  
  957.   if (p->parent == NULL)
  958.   {
  959.     v_list->vl[i]->acc_pointer = r;
  960.     goto end;
  961.   }
  962.   aux_node = p->parent;
  963.   r->right = aux_bool;
  964.   update(aux_node->link[aux_bool], r, i);
  965.  
  966.   if (!isred(aux_node, i))
  967.      goto end;
  968.  
  969.   q = aux_node;
  970.   p = q->parent;
  971.   root = v_list->vl[i]->acc_pointer;
  972.   while ((isred(child(0, p, i), i)) && (isred(child(1, p, i), i)))
  973.   {
  974.     temp = child(0, p, i);
  975.     up_col(temp->red, 0, i);
  976.     temp = child(1, p, i);
  977.     up_col(temp->red, 0, i);
  978.     up_col(p->red, 1, i);
  979.     if (p == root)
  980.       goto end;
  981.     r = p;
  982.     q = r->parent;
  983.     if (!isred(q, i))
  984.       goto end;
  985.     p = q->parent;
  986.   }
  987.   if (q->right == r->right)
  988.   {
  989.     up_col(p->red, 1, i);
  990.     up_col(q->red, 0, i);
  991.     newroot = single_rot(p, 1 - r->right, i);
  992.   }
  993.   else
  994.   {
  995.     up_col(r->red, 0, i);
  996.     up_col(p->red, 1, i);
  997.     newroot = double_rot(p, r->right, i);
  998.   }
  999.  
  1000.   if (newroot != NULL)
  1001.     v_list->vl[i]->acc_pointer = newroot;
  1002.  
  1003. end:
  1004.   m_b_root(i);
  1005.   return i;
  1006. }
  1007.  
  1008.  
  1009. Version pers_rb_tree::change_inf(pers_tree_node* p, void* info, Version i1)
  1010. {
  1011.   Version i = new_version(i1);
  1012.  
  1013.   p = search(p->key, i1);  // setting parent pointers
  1014.  
  1015.   pers_tree_node* pred = child(0,p,i);
  1016.   pers_tree_node* succ = child(1,p,i);
  1017.  
  1018.   copy_inf(info);
  1019.   pers_tree_node* q = newleaf(p->key,info, pred, succ, i);   
  1020.  
  1021.  
  1022.   if (pred) update(pred->link[1],q,i);
  1023.   if (succ) update(succ->link[0],q,i);
  1024.  
  1025.   q->right = p->right;
  1026.   update(p->parent->link[q->right], q, i);
  1027.  
  1028.   return i;
  1029.  
  1030. }
  1031.  
  1032.  
  1033.  
  1034. pers_tree_node* pers_rb_tree::min(Version v)
  1035. { pers_tree_node* r = v_list->vl[v]->acc_pointer;
  1036.   if (r == nil) return nil;
  1037.   while ( ! isleaf(r)) r = child(0,r,v);
  1038.   return r;
  1039. }  
  1040.  
  1041. pers_tree_node* pers_rb_tree::max(Version v)
  1042. { pers_tree_node* r = v_list->vl[v]->acc_pointer;
  1043.   if (r == nil) return nil;
  1044.   while ( ! isleaf(r)) r = child(1,r,v);
  1045.   return r;
  1046. }  
  1047.  
  1048. void pers_rb_tree::print(pers_tree_node *p, Version v)
  1049. { if (p)
  1050.   { if (isleaf(p))  
  1051.     { print_key(p->key);
  1052.       cout << " ";
  1053.      }
  1054.     else
  1055.      { print(child(0, p, v), v);
  1056.        print(child(1, p, v), v);
  1057.       }
  1058.    }
  1059. }  
  1060.  
  1061. void pers_rb_tree::del_tree()
  1062.   while (v_list->used)
  1063.   { pers_tree_node* p = v_list->used;
  1064.     v_list->used = v_list->used->next;
  1065.  
  1066.     f_rbclear(f_rchild(p->link[0]));
  1067.     delete p->link[0];
  1068.  
  1069.     f_rbclear(f_rchild(p->link[1]));
  1070.     delete p->link[1];
  1071.  
  1072.     if (p->copy != nil)
  1073.     {
  1074.       f_rbclear(f_rchild(p->copy));
  1075.       delete p->copy;
  1076.      }
  1077.  
  1078.     c_rbclear(c_rchild(p->red));
  1079.     delete p->red;
  1080.  
  1081.     if (isleaf(p))
  1082.     { clear_key(p->key);
  1083.       clear_inf(p->info);
  1084.      }
  1085.  
  1086.     delete p;
  1087.    }
  1088.  
  1089.    ver_node q;
  1090.    forall(q, v_list->vl) delete q;
  1091.  
  1092.    delete v_list;
  1093.  }  
  1094.  
  1095.  
  1096. pers_tree_node*  pers_rb_tree::lookup(void *val,Version v)
  1097. { pers_tree_node* p = search(val,v);
  1098.   return (p && cmp_keys(key(p), val) == 0) ? p : nil;
  1099.  }
  1100.  
  1101. pers_tree_node* pers_rb_tree::locate(void *val,Version v)
  1102. { pers_tree_node* p = search(val,v);
  1103.   return ( p && cmp_keys(key(p), val) >= 0) ?  p : nil;
  1104.  }
  1105.  
  1106. pers_tree_node* pers_rb_tree::locate_pred(void *val,Version v)
  1107. { pers_tree_node* p = search(val,v);
  1108.   if (p==0) return nil;
  1109.   if (cmp_keys(key(p), val) <= 0)  return p;
  1110.   return child(0,p,v);
  1111.  
  1112. }
  1113.  
  1114.  
  1115.  
  1116.  
  1117. void pers_rb_tree::draw(DRAW_NODE_FCT draw_node,
  1118.                         DRAW_EDGE_FCT draw_edge, 
  1119.                         Version v, pers_tree_node* r, 
  1120.                         double x1, double x2, double y, 
  1121.                         double ydist, double last_x)
  1122.  
  1123.   double x = (x1+x2)/2;
  1124.  
  1125.   if (r==NULL) return;
  1126.  
  1127.   if (last_x != 0) draw_edge(last_x,y+ydist,x,y);
  1128.  
  1129.   if (isleaf(r)) 
  1130.      draw_node(x,y,r->key);
  1131.   else
  1132.     { draw_node(x,y,get_key(r,v));
  1133.       draw(draw_node,draw_edge,v,child(0,r,v),x1,x,y-ydist,ydist,x);
  1134.       draw(draw_node,draw_edge,v,child(1,r,v),x,x2,y-ydist,ydist,x);
  1135.      }
  1136. }
  1137.  
  1138. void pers_rb_tree::draw(DRAW_NODE_FCT draw_node,
  1139.                         DRAW_EDGE_FCT draw_edge, 
  1140.                         Version v, double x1, double x2, double y, double ydist)
  1141. { draw(draw_node,draw_edge,v,v_list->vl[v]->acc_pointer,x1,x2,y,ydist,0); }
  1142.